/*
* Common utilities class
*/
public with sharing class Utilities {

  /*
  * Extracts list of ids from list of spbjects
  */
  public static List<ID> getListOfIds(List<Sobject> objects){
    if(objects == null){
        return new List<ID>();
    }
    List<ID> ids = new List<ID>();
  
    for(Sobject o : objects){
        ids.add((ID)o.get('Id'));
    }
    return ids;
  }
  
  /*
  * Extracts list of ids from list of spbjects
  */
  public static Set<ID> getSetOfIds(List<Sobject> objects){
    if(objects == null){
        return new Set<ID>();
    }
    Set<ID> ids = new Set<ID>();
  
    for(Sobject o : objects){
        ids.add((ID)o.get('Id'));
    }
    return ids;
  }
  
  /*
  * Escapes the string
  */
  public static String escapeStr(String str){
    if(str == null){
        return null;
    }else{
        return String.escapeSingleQuotes(str);
    }
  }
  
  /*
  * Returns set of ids for given field name. Usefull for example in triggers.
  */
  public static Set<ID> getReferenceIDSet(List<Sobject> objects, String refFieldName){
    Set<ID> ids = new Set<ID>();
    if(objects == null){
        return ids;
    }
  
    for(Sobject o : objects){
      try{  
        if(o.get(refFieldName) != null){    
          ids.add((ID)o.get(refFieldName));
        }
      }catch(Exception e){
        //Just don't add, the field was invalid
      }
    }
    return ids;
  }
  
  /*
  * Returns set of ids for given field name. Usefull for example in triggers.
  */
  public static Set<String> getReferenceStringSet(List<Sobject> objects, String refFieldName){
    Set<String> ret = new Set<String>();
    if(objects == null){
      return ret;
    }
  
    for(Sobject o : objects){
      try{  
        if(o.get(refFieldName) != null){  
        ret.add((String)o.get(refFieldName));
        }
      }catch(Exception e){
        //Just don't add, the field was invalid
      }
    }
    return ret;
  }

 /**
  * Returns map of unique field values and how many time they appeared.
  * Used in rollup emulation
  */  
  public static Map<String, Integer> getReferenceStringFrequencyMap(List<Sobject> objects, String refFieldName){
    Map<String, Integer> ret = new Map<String, Integer>();        
    if(objects == null){
      return ret;
    }
    
    for(Sobject o : objects){
      try{  
        if( o.get(refFieldName) != null ) {  
            String key = (String)o.get(refFieldName);
            if ( ret.containsKey(key) ) {
                ret.put(key, ret.get(key)+1);               
            }
            else {
                ret.put(key, 1);    
            }           
        }
      } catch(Exception e) {
        //Just don't add, the field was invalid
      }
    }
    return ret;
  }

    
  /*
  * Get set from label. Set type labels should be defined value1,value2,value3. If null the
  * empty list is returned. Trailing and leading whitespaces are removed from values. Because
  * the set is used it is guaranteed that only unique values are in set
  */ 
  public static Set<String> getSetValues(String strValue){
    Set<String> result = new Set<String>();
    if(strValue == null || strValue.length() == 0){
        return result;
     }
     
     String[] fields = strValue.split(',');
     for(String field : fields){
        result.add(field.trim());
     }
     return result;
  }
  
  /*
  * Sets field for all objects in the list to specific value. Throws illegal type if not ok
  */
  public static void setFieldValueSobjects(List<Sobject> objectsToBeModified, String fieldName, Object fieldValue){
     try{
        for(Sobject obj: objectsToBeModified){
            obj.put(fieldName, fieldValue);
        }
     }catch(Exception e){
        System.debug(e.getMessage());
        throw new IllegalTypeException('Cannot set the field named ' + fieldName + '. Check the schema.');
     }
    
  }
  
  public static Set<String> getMultiselectValues(String field){
    Set<String> setvalues = new Set<String>();
    if(field == null){
        return setvalues;
    }
    
    if(!field.contains(';')){
        setvalues.add(field);
        return setvalues;
    }
    
    String[] values = field.split(';');
    
    for(String value : values){
        if(value!= null || value.trim().length() != 0){
            setvalues.add(value.trim());
        }
    }
    
    return setvalues;
    
  }
  
  /*
  * Gets list of record types by name
  *
  */
  public static Set<ID> getRecordTypeIdSetWithNames(Set<String> names){
    Set<ID> ids = new Set<ID>();
    
    if(names == null){
        return ids;
    }
    
    for(String name : names){
        Schema.Recordtypeinfo info = Schema.SObjectType.Case.getRecordTypeInfosByName().get(name);
        if(info != null){
            ids.add(info.getRecordTypeId());
        }
    }
    
    return ids;
  }
  
  /*
  * Converts to integer. If not possible return 0
  */
  public static Integer strToInt(String num){
    try{
        Integer i = Integer.valueOf(num);
        return i;
    }catch(Exception e){
        return 0;
    }
  }
  
  public static Object nullCheck(Object checked, Object defaultValue){
    if(checked == null){
        return defaultValue;
    }else{
        return checked;
    }
  }
  
  public static boolean isEmpty(Decimal i){
    if(i == null || i == 0){
        return true;
    }
    return false;
  }

  /*
  * TEST METHODS BEGIN HERE
  */
  private static testMethod void testgetLitsOfIds(){
    List<Contact> cs = [select Id from Contact limit 100];
    List<ID> ids = getListOfIds(cs);
    
    System.assert(ids.size() == cs.size());
  }
  
  private static testMethod void testgetLitsOfIdsWithNull(){
    List<Contact> cs = null;
    List<ID> ids = getListOfIds(cs);
    
    System.assert(ids.isEmpty());
  }
  
  class IllegalTypeException extends Exception{}
}